<?php

  require_once "JooS/Helper/Broker.php";
  require_once "JooS/Server/Stream/Resource.php";

  final class JooS_Server {
    private $_request = null;

    private static $_routes = null;

    private static $_stackServers = array();

    public static function handle($request) {
      $newInstance = new self();
      array_push(self::$_stackServers, $newInstance);

      switch (true) {
        case (!($request instanceof JooS_Server_Request_Abstract)):
          self::throwException("\$request must be instance of JooS_Server_Request_Abstract");
        case ($request->getHost() === null):
          self::throwException("\$request must contain valid Hostname");
        case ($request->getResourceUri() === null):
          self::throwException("\$request must contain valid Resource Uri");
      }

      $controller = $newInstance->setRequest($request)->getController();
      $response = $controller->getResponse();

      array_pop(self::$_stackServers);

      return $response;
    }

    public static function getInstance() {
      return sizeof(self::$_stackServers) ? end(self::$_stackServers) : null;
    }

    protected function __construct() {
      JooS_Helper_Broker::helperBroker()->Server_InitHelper();
    }

    protected function setRequest(JooS_Server_Request_Abstract $request) {
      $this->_request = $request;
      return $this;
    }

    public function getRequest() {
      return $this->_request;
    }

    public static function addRoute(JooS_Server_Route_Abstract $route) {
      self::$_routes[] = $route;
    }

    public static function clearRoutes() {
      self::$_routes = array();
    }

    protected function getRoutes() {
      if (is_null(self::$_routes)) {
        $routes = JooS_Helper_Broker::helperBroker()->Server_RouteHelper->get();

        self::$_routes = array();
        foreach ($routes as $route)
          self::addRoute($route);
      }
      return self::$_routes;
    }

    public function getController() {
      $request = $this->getRequest();
      $routes = $this->getRoutes();

      $className = null;
      foreach ($routes as $route) {
        if ($route->test($request)) {
          $className = $route->getClassName();
          break;
        }
      }

      require_once "JooS/Server/Controller/404.php";

      if (is_null($className))
        $controller = new JooS_Server_Controller_404($request);
      else {
        try {
          require_once "Zend/Loader.php";
          @Zend_Loader::loadClass($className);

          $rClass = new ReflectionClass($className);
          $controller = $rClass->newInstance($request);
        }
        catch (Zend_Exception $e) {
          $controller = new JooS_Server_Controller_404($request);
        }
      }
      return $controller;
    }
    
    protected static function throwException($message, $code = 0) {
      require_once "JooS/Server/Exception.php";

      throw new JooS_Server_Exception($message, $code);
    }
  }

?>